package com.xpc.consumer.spring.scanner;

import java.io.File;
import java.io.FileFilter;
import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

public class ClassScanner {


    private static final String CLASS_FILE_SUFFIX = ".class";

    private static final String CHARSET_UTF = "UTF-8";

    /**
     * 根据传入的包名，来获取所有的.class文件
     * @param packageName 传入的包名
     * @return
     * @throws Exception
     */
    public static List<String> getClassList(String packageName) throws Exception{
        List<String> classList = new ArrayList<>();
        String packageDirName = packageName.replace(".","/");
        Enumeration<URL> fileDir = Thread.currentThread().getContextClassLoader().getResources(packageDirName);

        while (fileDir.hasMoreElements()) {
            //获取下一个元素
            URL url = fileDir.nextElement();
            //获取包的物理路径
            String filePath = URLDecoder.decode(url.getFile(), CHARSET_UTF);
            findClassByFile(filePath,packageName,classList);
        }
        return classList;
    }

    public static void findClassByFile(String filePath,String packageName, List<String> classList) {
        File dir = new File(filePath);
        //如果不存在，或者不是一个目录就直接返回
        if(!dir.exists() || !dir.isDirectory()) {
            return;
        }

        File[] listFiles = dir.listFiles(new FileFilter() {
            @Override
            public boolean accept(File file) {
                return (file.isDirectory()) || file.getName().endsWith(CLASS_FILE_SUFFIX);
            }
        });

        for(File file : listFiles) {
            if(file.isDirectory()) {
                String fileAbsolutePath = file.getAbsolutePath();
                String[] fileSplits = fileAbsolutePath.split("/");
                String newPackageName = packageName + "." + fileSplits[fileSplits.length-1];
                findClassByFile(file.getAbsolutePath(),newPackageName,classList);
            }else {
                //如果是java文件，就去掉.class,只留下类名
                String className = file.getName().substring(0, file.getName().length() - 6);
                classList.add(packageName + "." +className);
            }
        }
    }
}
